package com.stars.module.user.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.stars.base.constants.SystemConstants;
import com.stars.base.constants.SystemSettingConstants;
import com.stars.base.entity.CommonDTO;
import com.stars.base.entity.Result;
import com.stars.base.entity.SessionUser;
import com.stars.module.department.entity.StarDept;
import com.stars.module.department.mapper.StarDeptMapper;
import com.stars.module.department.service.impl.StarDeptServiceImpl;
import com.stars.module.user.entity.StarOrgUser;
import com.stars.module.user.entity.StarUser;
import com.stars.module.user.mapper.OrgUserMapper;
import com.stars.module.user.mapper.UserMapper;
import com.stars.module.user.service.StarUserService;
import com.stars.util.common.DevelopKit;
import com.stars.util.ecrypt.MD5Util;
import org.apache.shiro.util.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

@Service
public class StarUserServiceImpl implements StarUserService {

    private final UserMapper userMapper;
    private final OrgUserMapper orgUserMapper;
    private final StarDeptMapper deptMapper;

    public StarUserServiceImpl(UserMapper userMapper, OrgUserMapper orgUserMapper, StarDeptMapper deptMapper) {
        this.userMapper = userMapper;
        this.orgUserMapper = orgUserMapper;
        this.deptMapper = deptMapper;
    }

    @Override
    public JSONObject loadUserByDeptId(CommonDTO dto) {
        dto.setCurrent(dto.getCurrent()-1);
        JSONObject result = new JSONObject();

        result.put("list",userMapper.loadUserByDeptId(dto));
        result.put("total",userMapper.userCountByDeptId(dto));

        return result;
    }

    @Override
    public JSONObject loadUserByRoleId(CommonDTO dto) {
        dto.setCurrent(dto.getCurrent()-1);
        JSONObject result = new JSONObject();

        result.put("list",userMapper.loadUserByRoleId(dto));
        result.put("total",userMapper.userCountByRoleId(dto));

        return result;
    }

    @Override
    public StarUser loadUserById(String uid) {
        return userMapper.selectById(uid);
    }

    @Override
    @Transactional
    public boolean saveOrUpdateUser(StarUser user) {
        boolean result;

        if(StringUtils.hasLength(user.getId())){
            //有ID，更新
            result = userMapper.updateById(user) > 0;
        }else{
            //无ID，新增
            String userId = DevelopKit.generateUUID();
            user.setId(userId);
            String defaultPwd = DevelopKit.getStringFromDBConfig(SystemSettingConstants.SYS_DEFAULT_PASSWORD, SystemConstants.DEFAULT_PASSWORD);
            String password = MD5Util.md5(defaultPwd);
            user.setPassword(password);

            DevelopKit.setBaseInfo(user);

            StarOrgUser starOrgUser = new StarOrgUser();
            starOrgUser.setId(DevelopKit.generateUUID());
            starOrgUser.setUserId(userId);
            starOrgUser.setOrgId(user.getDeptId());
            starOrgUser.setIsMain(1);
            starOrgUser.setShowOrder(user.getShowOrder());
            DevelopKit.setBaseInfo(starOrgUser);
            result = userMapper.insert(user)>0 && orgUserMapper.insert(starOrgUser)>0;
        }
        return result;
    }

    @Override
    public Integer getMaxIndex(String fid) {
        QueryWrapper<StarOrgUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(StarOrgUser::getOrgId,fid);
        queryWrapper.select("MAX(SHOWORDER) AS SHOWORDER");
        StarOrgUser starOrgUser = orgUserMapper.selectOne(queryWrapper);
        return starOrgUser!=null?starOrgUser.getShowOrder():0;
    }

    @Override
    public boolean removeUser(String uid,String deptId) {

        QueryWrapper<StarOrgUser> orgUserQueryWrapper = new QueryWrapper<>();
        orgUserQueryWrapper.lambda().eq(StarOrgUser::getOrgId,deptId).eq(StarOrgUser::getUserId,uid);

        return orgUserMapper.delete(orgUserQueryWrapper)>0 && userMapper.deleteById(uid)>0;
    }

    @Override
    public boolean saveOrgUser(StarOrgUser starOrgUser) {
        return orgUserMapper.insert(starOrgUser)>0;
    }

    /**
     * 设置兼职部门/主部门
     * @param uid
     * @param deptIds
     * @return
     */
    @Override
    public Result putPartTimeDept(String uid, String deptIds, Integer isMain) {
        SessionUser sessionUser = DevelopKit.getSessionUser();
        //设置主部门
        if(isMain == 1){
            orgUserMapper.updatePartTimeDept(uid);

            LambdaQueryWrapper<StarOrgUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StarOrgUser::getUserId,uid)
                    .eq(StarOrgUser::getOrgId,deptIds);
            StarOrgUser starOrgUser = orgUserMapper.selectOne(wrapper);
            starOrgUser.setIsMain(1);
            orgUserMapper.updateById(starOrgUser);
        }
        //设置兼职部门
        else{
            String[] depts = deptIds.split(",");
            Arrays.stream(depts).forEach(dept->{
                StarOrgUser starOrgUser = new StarOrgUser();
                starOrgUser.setId(DevelopKit.generateUUID());
                starOrgUser.setUserId(uid);
                starOrgUser.setOrgId(dept);
                starOrgUser.setIsMain(isMain);
                starOrgUser.setRowStatus(1);
                starOrgUser.setCreateUserId(sessionUser.getUserId());
                starOrgUser.setCreateUserName(sessionUser.getUserName());
                orgUserMapper.insert(starOrgUser);
            });
        }
        return Result.success();
    }

    /**
     * 获取用户部门关系
     * @param uid
     * @return
     */
    @Override
    public JSONObject loadUserPartTimeDept(CommonDTO dto) {
        List<StarOrgUser> orgUsers = orgUserMapper.selectJoinList(StarOrgUser.class,new MPJLambdaWrapper<StarOrgUser>()
                .leftJoin(StarDept.class,StarDept::getId,StarOrgUser::getOrgId)
                .selectAs(StarDept::getOrgName,StarOrgUser::getOrgName)
                .select(StarOrgUser::getIsMain)
                .select(StarOrgUser::getOrgId)
                .eq(StarOrgUser::getUserId,dto.getFid())
                .orderByAsc(StarDept::getShowOrder));

        JSONObject result = new JSONObject();
        result.put("list",orgUsers);
        result.put("total",orgUsers.size());
        return result;
    }
}